home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d18
/
tpa2_a.arc
/
DOSEXEC.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-04-28
|
5KB
|
129 lines
{$M $4000,0,0}
{═══════════════════════════ DOSEXEC.PAS ════════════════════════════}
{ Usage: Dosexec (From Editor, just Run) }
{ (prompts for Program to run) }
{═══════════════════════════ DOSEXEC.PAS ════════════════════════════}
{- This demonstration illustrates the use of "local" CSeg assembly }
{- variables allocated in the 1st Block of the current Code Segment. }
{- This is a powerful but somewhat complicated technique that you }
{- may NEVER need to use. (It is useful for creating customized }
{- Exec Procedures, and Interrupt Routines that can 'Chain' rather }
{- than Iret). For now, just run the demonstration, and keep in }
{- the back of your mind that variables CAN be stored in the Code }
{- segment if you should ever find it necessary. }
{- NOTE: this demonstration program does not parse the parameters }
{- into the 'default FCBs', so some programs (including diskcopy, }
{- format, chkdsk, etc) cannot be run directly. However, using }
{- example 2 below, you can shell to DOS and run these programs. }
{═════════════════════════════ Examples ═════════════════════════════}
{ ( <CR> signifies Carriage Return ) }
{ 1. To list a directory on a system with a bootable hard disk: }
{ At the 'Path' prompt: --> C:\command.com<CR> }
{ At the 'Parameters' prompt: --> /c dir<CR> }
{ 2. To shell to DOS with a system disk in drive A: }
{ At the 'Path' prompt: --> A:\command.com<CR> }
{ At the 'Parameters' prompt: --> <CR> }
{ ( Type EXIT<CR> to return to Turbo ) }
{═════════════════════════════ Examples ═════════════════════════════}
{════════════════════════════ Exec ═════════════════════════════}
{ Execute specified Path and Command Line or return Error in }
{ global VAR DosError. Compatable with DOS Unit Exec Procedure }
{════════════════════════════ Exec ═════════════════════════════}
VAR DosError: Integer;
PROCEDURE Exec(Path,CmdLine: String);
VAR
{- local var addr are assigned in reverse order -}
FCB6C: Pointer; { Dword pointer to FCB2 (6CH in PSP) }
FCB5C: Pointer; { Dword pointer to FCB1 (5CH in PSP) }
CmdPtr: Pointer; { Dword pointer parameter string }
EnvSeg: WORD; { Segment address of environment }
PathPtr: Pointer; { Dword pointer Path to Exec }
BEGIN
Assemble
Jmp Begin
SaveSs Dw 0 ; Ss and Sp MUST be saved in our Code Segment
SaveSp Dw 0 ; Int $21 Function $4B does not restore them
Begin:
Push Ds,Bp
Mov SaveSs,Ss ; TP&Asm automatically supplies the needed
Mov SaveSp,Sp ; Cs overrides for SaveSs and SaveSp
;- You can code the override explicitly (Cs Mov SaveSs,Ss) if you
;- prefer, and you can disable Presumptions for "WYSIWYG" assembly
Mov W CmdPtr+2,Ss ; Save Command Line segment
Lea AX,CmdLine
Mov W CmdPtr,Ax ; And offset in Parameter Block.
;- Technical Note: For String Value Parameters, Turbo 4/5 pushes
;- a Pointer to a Copy of the String Value. The pointer will
;- reference either the Local Copy OR a "Packed" copy in the
;- callers Code Segment. Since we will be modifying the Path
;- string (to add a zero byte), it is essential that we use
;- the Local copy and not a Code Seg copy. For this reason
;- we do NOT want to use the Pointers at [Bp+4] and [Bp+8].
;- Instead, take advantage of the fact that TP&Asm allows
;- reference to parameters BY NAME - the resulting code is
;- easier to understand, and Value parameters referenced by
;- name will ALWAYS refer to a local copy in the Stack segment
Push Ss ; Point ES:BX to Parameter Block
Pop Es
Lea Bx,EnvSeg ; Use LEA since EnvSeg is implicitly indexed (by BP)
Mov EnvSeg,0 ; Pass a copy of the current enviroment
Push Ss
Pop Ds
Lea Si,Path ; Point DS:SI to length byte of LOCAL COPY
Xor Ax,Ax
Mov Al,[Si] ; Get length
Inc Si
Mov Dx,Si ; Point DS:DX to program name
Add Si,Ax ; Point past Last Char
Mov b[Si],0 ; Make it AsciiZ in LOCAL COPY
Mov Ax,4B00h ; DOS EXEC function: al=0, ah=4Bh
Int 21h ; Execute
IF NC Xor Al,Al ; If successful (No Carry), clear error code
; 'IF' is an A86 specialty, supported for compatibility
Xor Ah,Ah
Cli
Mov Ss,SaveSs ; restore our Stack
Mov Sp,SaveSp
Sti
Pop Bp,Ds ; Restore Turbo Bp and Ds
Mov DosError,Ax ; Store DosError AFTER restoring DS
end; {Assemble}
END; {Exec}
VAR Path,CmdLine: String;
{════════════════════ Demonstrate Exec Call ════════════════════}
BEGIN {Main Program}
WRITELN('Path and Program to execute [e.g. C:\Command.com]');
WRITE('--> '); READLN(Path);
WRITELN('Parameters for executing program [e.g. /C Dir]');
WRITE('--> '); READLN(CmdLine);
WRITELN('Before Exec');
Exec(Path,CmdLine);
CASE DosError OF
0: WRITELN('Successful Exec');
2: WRITELN('File ',Path,' Not Found');
8: WRITELN('Not Enough Memory to Exec ',Path);
ELSE WRITELN('Exec Failed: Dos Error ',DosError);
END; {CASE DosError}
END.